home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.02 Feb 96 / MacApp2PPC Text < prev   
Encoding:
Text File  |  1996-01-03  |  12.6 KB  |  96 lines  |  [TEXT/ttxt]

  1. Porting Your Source Code
  2. Along the way to developing MacApp2PPC, we tried to come up with tools and hints for making the leap to PowerPC with your own code.  The result is a set of MPW scripts that you can execute to do most of the conversion work for you.  However, because MacApp2PPC was constructed to minimize the damage to your own code, you may be surprised at how little time it would take you to port even without the MPW scripts.
  3. Running the scripts is easy, provided you can already tolerate MPW.
  4.  
  5. 1.    Install MacApp2PPC and a minimal MPW according to the instructions provided on your compiler vendor’s CD.  It is best to use a fresh MPW setup, not one that you’re already using.
  6. 2.    Start up MPW.  Confirm that MacApp2PPC installed correctly (its menu is added to the menu bar).
  7. 3.    Set the current directory to one containing your Pascal source code, and select Convert Directory from the MacApp2PPC menu.  Several dictionary files are run against your code using the MPW Canon tool.  This performs the majority of the Toolbox renaming changes.
  8. 4.    You can run a script called CreateUPPChecker to find out where all of your ProcPtrs live, because you will have to change them to create UniversalProcPtrs.  Because this script takes a long time to run, it’s best to start it at night and return to it the next day (or the next, depending on how large your application is).
  9.  
  10. By this point, most developers cut to the chase, try to build, and wade through the remaining compiler and linker errors.  We’ll cover a few of them here.
  11. Changing those Pesky ProcPtrs
  12. One common hang-up in the migration to PowerPC is the need to replace ProcPtrs with UniversalProcPtrs for Toolbox callbacks.  We’ll take a moment to describe how to change a ProcPtr through an example in MacApp 2 itself.
  13. The process goes like this: you have identified a ProcPtr that must be changed.  You need to create a UniversalProcPtr for that procedure pointer, and use that UPP in its place.  The UPP is a record that includes your procedure pointer, information about whether it’s compiled for 68K, and other housework.  If you use that UPP repeatedly or in a modeless manner (for example, a TextEdit clickLoop callback), you might hang on to it; otherwise, you will usually dispose of the storage used by the UPP right after making your Toolbox call.
  14. For example, in MacApp 2 for PowerPC, when Finder printing, we use the Apple event Toolbox call AEInteractWithUser to make sure we get the user’s attention before putting up the print dialog box.  This call has a callback to our own code, so that we can idle while the Apple event manager is off waving its hand in front of the user.  Here is the interface to the idle function.
  15.  
  16. FUNCTION IdleFunction (
  17.         VAR event:            EventRecord;
  18.         VAR sleepTime:    Longint;
  19.         VAR mouseRgn:        RgnHandle): BOOLEAN;
  20.  
  21. Before porting to PowerPC, the address of this function would be passed directly to the Toolbox:
  22.  
  23. FailOSErr(AEInteractWithUser(
  24.         kAEDefaultTimeout, NIL, @IdleFunction))
  25.  
  26. For PowerPC, to create the UPP automatically, we go searching for the Toolbox file that contains the definition for the relevant function, in the hope of finding a definition for its UPP and an automatic conversion function.  In this example, the Toolbox file is AppleEvents.p; lo and behold, there is an AEIdleUPP type and NewAEIdleProc conversion function provided for us.  Because we no longer need the UPP when we are through, we will dispose of it when finished.  So, in order to call AEInteractWithUser, we add a local variable and change the AEInteractWithUser code.
  27.  
  28. VAR
  29.     idleUPP:    AEIdleUPP;
  30.  
  31.     idleUPP := NewAEIdleProc(@idleFunction); 
  32.     FailNIL(idleUPP);
  33.     FailOSErr(AEInteractWithUser(kAEDefaultTimeout, NIL, idleUPP));
  34.     idleUPP := DisposeIfRoutineDescriptor(idleUPP);
  35.  
  36. When building for 68K, this changed code still works, that’s why it’s called Universal.  In fact on 68K it does the same thing as before: NewAEIdleProc simply returns the @, and DisposeIfRoutineDescriptor does nothing.  We are doing this extra work for PowerPC builds.
  37. Working with fp and fenv
  38. Another area of difficulty in porting your own code to PowerPC is likely to be the use of SANE or the 68881 (math coprocessor), if you do a lot of floating point math in your application.  The good news is that the MPW porting scripts provided with MacApp2PPC make a lot of the changes for you to use the PowerPC MathLib through fp.p and fenv.p.  Still, there are a few gaps.
  39. For example, the Num2Str and Str2Num functions aren’t provided by MathLib.  This bothered key developers porting MacApp2PPC, so these are now provided in UMacAppUtilities.  If you already include UMacAppUtilities or UMacApp, you can continue using Num2Str and Str2Num as is.  Note that the string parameter was changed from DecStr to Str255.
  40. MacApp 2 API Changes
  41. Aside from new interfaces and methods, the only major API change is in TApplication:GetActiveWindow, which now requires a Boolean parameter similar to MacApp 3.  kFloatersOK and kFloatersNotOK are defined for you.  If you use this function, the returned window can be a floating window or a regular window.  When in doubt about how you need it to behave, use kFloatersNotOK.
  42. Other important API changes include accepting UniversalProcPtrs instead of regular ProcPtrs (consult the previous description of converting to UPPs for help in changing your ProcPtrs).
  43. Finally, UPatch’s mechanism for patching traps has changed to conform to the MacApp 3.1 mechanism, which is friendlier for PowerPC trap patching.  If you use UPatch directly, you will have to change the way you patch traps.  Consult UPatch and MacApp 3.1 documentation for details.
  44. What’s More
  45. We wouldn’t be able to call ourselves good hackers if there wasn’t a surprise or two in the converted MacApp 2.  One surprise is integrated support for floating windows.  There is an unsupported trap-patched floating windows unit used by a lot of MacApp 2 developers, but nobody wanted to wade through the gunk in porting that code, which is buggy anyway.  So, Cheryl Lins and I looked at MacApp 3.1’s support for floating windows, and we back-ported those changes into MacApp 2.  It was easier than it sounds.  The result is cleaner, integrated floating window support in the framework, and no trap patching.  Finally, code for Balloon Help was mixed in with the code that supports Apple events (which Anil Bajaj originally wrote as a patch to MacApp 2 using Keith Rollin’s excellent PatchMaker).
  46. Apple events in MacApp 2
  47. Several API functions are added for Apple event support.  Default support for the required Apple events 'oapp', 'odoc', 'pdoc', and 'quit' are implemented in TApplication.
  48. You can support Apple events very easily with MacApp2PPC.  You first create a new 'aedt' resource in your <app>.r file specifying the event class, event message, and a CmdNumber (for an example look at the 'aedt' resource in the MacApp.r file).  The next and only other thing you have to do is override the TEvtHandler method DoAECommand and handle the appropriate CmdNumber (just like you would in DoMenuCommand, etc.).
  49.  
  50.  
  51. DoAECommand interface
  52.  
  53. { If the handler can perform the apple event command it }
  54. { does so by either performing the command directly or }
  55. { by posting a TCommand. NOTE: Both UNIV Ptr’s are }
  56. { actually a Ptr to an Apple event record }
  57.  
  58. FUNCTION TEvtHandler.DoAECommand (
  59.                 aCmdNumber:    CmdNumber;
  60.                 message:        UNIV Ptr;
  61.                 reply:            UNIV Ptr): TCommand;
  62.  
  63. In addition, there are two utility routines (in UMacAppUtilities):
  64.  
  65. •    MissedRequiredAEParameters checks the passed-in Apple event for any required parameters that we may have missed (called if handling Apple events, which should not have any parameter like the open application and quit events.)
  66. •    ProcessAEDocList extracts the list of documents from the Apple event’s direct parameter and converts each document’s FSSpec record to an AppFile record; then calls the passed-in routine (used to handle the open document and print document events).
  67.  
  68. Note: Your 'size' resource must have its isHighLevelEvents flag set in order for your application to receive Apple events.  All of the MacApp2PPC example applications have this set already.
  69. Floating windows
  70. Floating window support was integrated into TApplication and TWindow.  If you wish to add floating windows to your application, all you need to do is call InitUFloatWindow to ensure that the TFloatWindow subclass isn’t dead-stripped.
  71. To make a window floating, make your window resource class name a TFloatWindow instead of TWindow, and add the following to your .r file:
  72.  
  73. #include "FloatWindow.r"
  74.  
  75. This adds the System 7.5 floating window WDEF to your application, so that you have floating windows on older Macintosh systems.  If you’ve been reading this article and you’re skeptical of the value of object-oriented frameworks, notice the number of lines of source code the developer must write to use floating windows (answer: one line, and that’s just to trick the linker!).
  76. New Building Blocks
  77. Actually, none of these building blocks are new, but they’ve moved from the MacApp examples into the main part of the MacApp library.  If you are already using them, you will be mildly relieved to know they have been ported to PowerPC.  You can remove them from your application source code, as well as from your MAMake file (if you’re using MPW).
  78. These building blocks include:
  79. UBetterFeedbackCmd    VBL-synchronized feedback
  80. UFloatWindow    Floating window support
  81. UGrabberTracker    That MacPaint hand-grabber thingy
  82. UMenu    TView descendants that can appear in menus
  83. USynchScroller    Scrolling multiple views simultaneously
  84. UTearOffMenu    What it says
  85. UVUAssist    Virtual User support (OK, I lied, this is 68K
  86.     only)
  87. Compiler-Specific Details
  88. It’s worth mentioning one compiler-specific detail for each Object Pascal compiler.
  89. Language Systems Pascal 1.0 works under MPW; that means it uses the MABuild tool to build MacApp applications.  MABuild has been modified to accept additional options, including -[No]PPC to indicate 68K vs.  PowerPC code generation.  That’s all there is to it!  When a future version is provided as a plug-in for the Symantec IDE, the build process will use the features in the IDE more directly.
  90. Metrowerks CodeWarrior Pascal works within the CodeWarrior IDE so the IDE is used for building applications, but MacApp 2 still requires compiling resources under MPW.  Although there is a Rez plug-in for the CW IDE, MacApp 2 still relies on a custom MPW tool called PostRez.  To make life easier for the CW Pascal user, the revised MABuild tool also accepts a -[No]OnlyResources option, to specify that you wish to compile (and PostRez) only resources for your application.  This step is still annoying enough that Per Bergland and Roger Brown are seeking ways to remove or simplify the PostRez step, by developing a plug-in tool.  Their dedication captures the spirit of what is MacApp2PPC.
  91. And Finally
  92. Well over a dozen applications have been ported to PowerPC using MacApp2PPC, and many more are currently being ported.  Meanwhile, the world of software frameworks is constantly shifting.  Component technology is moving rapidly to your neighborhood.  MacApp2PPC is currently serving the needs of Macintosh Object Pascal MacApp 2 developers wishing to have native applications on PowerPC.  Where it goes depends on the developers who use and nurture this version of the framework.  There is no commitment except the one each developer gives to it.  Some developers are sufficiently motivated to continue evolving MacApp 2 in manners consistent with the drive towards MacApp 3.3 as its flagship, and in moving developers toward OpenDoc as the future.
  93. Developers in the cooperative are considering adding drag and drop support as an initial step toward OpenDoc container support, removing the working directories dependency, and removing the PostRez step mentioned earlier.  If you want to make a difference and help out in making these changes, you can join the “MacApp2PPC-List” Internet mailing list by sending e-mail to macjordomo@afar.med.cornell.edu with “subscribe MacApp2PPC-List  Your_Name” in the body of the message; send e-mail to arnold@lumina.com if you need help.  Macjordomo (http://leuca.med.cornell.edu/Macjordomo) is a listserver that Michele Fuortes ported to PowerPC using MacApp2PPC in about 5 evenings.  You are also highly encouraged to subscribe to the comp.lang.pascal.mac newsgroup on the Internet to stay in tune with the latest goings-on in Pascal for the Macintosh.
  94. Also, check out the cooperative’s Internet world wide web pages at:  http://www.lumina.com/arnold/MacApp2PPC.html
  95. You’ll find some interesting things for MacApp 2 at this site, including the latest version of MacApp 2 for PowerPC, plus WASTE text engine support, QuickDraw GX printing support, and more.
  96. What this cooperative brings Object Pascal MacApp 2 developers in the future is yet unseen.  Stay tuned.